﻿using System;
using System.Collections.Generic;
using BBCode.Nodes;
using BBCode.Template;

namespace BBCode.Tags
{
    /// <summary>
    /// Smiley tag.
    /// </summary>
    public class Smiley : ITag
    {
        private readonly IEnumerable<string> _aliases;
        private readonly bool _canHaveChildren;
        private readonly string _name;
        private readonly int _priority;
        private readonly string _templateName;
        private readonly string _url;

        /// <summary>
        /// Initializes a new instance of the <see cref="Smiley"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="aliases">The aliases.</param>
        /// <param name="url">The URL.</param>
        /// <param name="templateName">Name of the template.</param>
        public Smiley(string name, IEnumerable<string> aliases, string url, string templateName = "Smiley.html")
        {
            _name = name;
            _canHaveChildren = false;
            _priority = 0;
            _aliases = aliases;
            _url = url;
            _templateName = templateName;
        }

        /// <summary>
        /// Gets the aliases.
        /// </summary>
        public IEnumerable<string> Aliases
        {
            get { return _aliases; }
        }

        /// <summary>
        /// Gets the URL.
        /// </summary>
        public string URL
        {
            get { return _url; }
        }

        #region ITag Members

        /// <summary>
        /// Gets the name of the template.
        /// </summary>
        /// <value>
        /// The name of the template.
        /// </value>
        public string TemplateName
        {
            get { return _templateName; }
        }

        /// <summary>
        /// Gets the template.
        /// </summary>
        /// <returns>The NVTemplate.</returns>
        public NVTemplate GetTemplate()
        {
            return new NVTemplate(TemplateName);
        }

        /// <summary>
        /// Gets a value indicating whether this instance can have children.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance can have children; otherwise, <c>false</c>.
        /// </value>
        public bool CanHaveChildren
        {
            get { return _canHaveChildren; }
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        public string Name
        {
            get { return _name; }
        }

        /// <summary>
        /// Gets or sets the type of the parse.
        /// </summary>
        /// <value>
        /// The type of the parse.
        /// </value>
        public ParseType ParseType { get; set; }

        /// <summary>
        /// Gets the priority.
        /// </summary>
        public int Priority
        {
            get { return _priority; }
        }

        /// <summary>
        /// Gets the nodes.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>The discovered tags.</returns>
        public IEnumerable<INode> GetNodes(string text)
        {
            IList<Nodes.Smiley> results = new List<Nodes.Smiley>();

            foreach (var alias in Aliases)
            {
                var index = text.IndexOf(alias, StringComparison.OrdinalIgnoreCase);

                while (index != -1)
                {
                    //Find original indexes
                    var nodeText = text.Substring(index, alias.Length);
                    var nodeIndex = new NodeIndex {Beginning = index, End = index + alias.Length};

                    var smiley = new Nodes.Smiley(this, nodeText, nodeIndex);
                    results.Add(smiley);

                    index = text.IndexOf(alias, index + 1, StringComparison.OrdinalIgnoreCase);
                }
            }

            return results;
        }

        #endregion
    }
}